# Text Line Combine Node for ComfyUI
# Copyright (C) 2025 Reiner Prokein
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# comfyui_text_line_combine/combine_node.py

class CombineTextLines:
    @classmethod
    def INPUT_TYPES(cls):
        """
        Defines the input types that should be shown in the UI for this node.
        The node can accept either raw text or a path to a file containing the text.
        If both are supplied, the file content takes precedence.
        """
        return {
            "required": {
                # Raw text fields
                "text_a": ("STRING", {"multiline": True,
                                      "display_name": "Text A (raw)"}),
                "text_b": ("STRING", {"multiline": True,
                                      "display_name": "Text B (raw)"}),
                "use_text_c": ("BOOLEAN", {"default": False,
                                           "display_name": "Use Text C? "
                                                           "(Text C will only be included if checked)"}),
                "text_c": ("STRING", {"multiline": True, "default": "",
                                      "display_name": "Text C (optional raw, used only if checkbox is checked)"}),

                # File‑path fields
                "text_a_path": ("STRING", {"default": "",
                                           "display_name": "Path to Text A file"}),
                "text_b_path": ("STRING", {"default": "",
                                           "display_name": "Path to Text B file"}),
                "text_c_path": ("STRING", {"default": "",
                                           "display_name": "Path to Text C file (optional)"}),

                # Separator
                "separator": ("STRING", {"default": " ",
                                         "display_name": "Separator"})
            }
        }

    RETURN_TYPES = ("STRING",)
    FUNCTION = "combine"
    CATEGORY = "Text"

    def _load_text_from_path(self, path: str) -> str:
        """
        Helper that returns the content of a file if a non‑empty path is supplied.
        If the file cannot be read, an empty string is returned.
        """
        if not path.strip():
            return ""
        try:
            with open(path, "r", encoding="utf-8") as f:
                return f.read()
        except Exception:
            return "An error occured"

    def combine(self,
                text_a: str,
                text_b: str,
                use_text_c: bool = False,
                text_c: str = "",
                text_a_path: str = "",
                text_b_path: str = "",
                text_c_path: str = "",
                separator: str = " ") -> tuple:
        """
        Combines the lines of Text A, B (and optionally C) using the given separator.
        If a path is provided for a text field, its content overrides the raw input.
        """

        # Resolve final texts – file content takes precedence over raw input
        txt_a = self._load_text_from_path(text_a_path) or text_a
        txt_b = self._load_text_from_path(text_b_path) or text_b

        txt_c = ""
        if use_text_c:
            txt_c = self._load_text_from_path(text_c_path) or text_c

        # Split into line lists
        lines_a = txt_a.splitlines()
        lines_b = txt_b.splitlines()

        line_lists = [lines_a, lines_b]

        if use_text_c and txt_c.strip() != "":
            lines_c = txt_c.splitlines()
            line_lists.append(lines_c)

        # Determine the longest list length
        max_len = max(len(lst) for lst in line_lists)

        # Pad shorter lists with empty strings
        for lst in line_lists:
            if len(lst) < max_len:
                lst += [""] * (max_len - len(lst))

        # Build combined lines – filter out empties to avoid leading separators
        out_lines = []
        for i in range(max_len):
            parts = [lst[i] for lst in line_lists if lst[i]]   # ← skip empty strings
            combined_line = separator.join(parts)
            out_lines.append(combined_line)

        return ("\n".join(out_lines),)   # ComfyUI expects a tuple as output
